<script setup>
import { ref, computed } from 'vue'
import http from '@/utils/http'
import * as echarts from 'echarts'
import formatDate, { getDate, getWeekRangeOfYear } from '@/utils/date'
const eventLevelEcharts = ref(null)
const eventTypeEcharts = ref(null)
const eventHandleRef = ref(null)
import { DeviceApi } from '@/api/device'
import colorTools from '@/utils/colorTools'
import { Download } from '@element-plus/icons-vue'
import { fetchDownData } from '@/api/event.services'
import { ElLoading } from 'element-plus'
import { fetchEventHandle } from '@/api/statistics.service'
let eventChars = null
const initEventTypeEcharts = () => {
    if (!eventChars) {
        eventChars = echarts.init(eventTypeEcharts.value)
    }
    const data = type.value.value || []
    const color = colorTools().initColor(data.length)
    data.forEach((item, index) => {
        item.itemStyle = { color: color[index] }
    })
    const option = {
        title: {
            text: '事件类型分布',
            textStyle: {
                fontSize: 14,
                fontWeight: 'bold'
            }
        },
        tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
            bottom: 10,
            left: 'center',
            data: type.value.name
        },
        series: [
            {
                type: 'pie',
                name: '事件分析',
                type: 'pie',
                radius: ['0%', '55%'],
                center: ['50%', '45%'],
                selectedMode: 'single',
                data: data,
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                },
                label: {
                    show: true, // 显示标签
                    position: 'outside', // 标签位置在外侧
                    formatter: '{b}: {c} ({d}%)', // 标签显示格式
                    fontSize: 12
                },
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                }
            }

        ]
    }

    eventChars.setOption(option)
}

let levelChars
const initEventLevelEcharts = () => {
    if (!levelChars) {
        levelChars = echarts.init(eventLevelEcharts.value)
    }
    const data = level.value.value || []
    const color = colorTools().initColor(data.length)
    data.forEach((item, index) => {
        item.itemStyle = { color: color[index] }
    })
    const option = {
        title: {
            text: '事件警情分布',
            textStyle: {
                fontSize: 14,
                fontWeight: 'bold'
            }
        },
        tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
            bottom: 10,
            left: 'center',
            data: level.value.name
        },
        series: [
            {
                name: '警情分析',
                type: 'pie',
                radius: ['0%', '55%'],
                center: ['50%', '45%'],
                selectedMode: 'single',
                data: data,
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                },
                label: {
                    show: true, // 显示标签
                    position: 'outside', // 标签位置在外侧
                    formatter: '{b}: {c} ({d}%)', // 标签显示格式
                    fontSize: 12
                },
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                }
            }
        ]
    }

    levelChars.setOption(option)
}

const eventAreaEcharts = ref(null)
let areaChars = null
let areaFilterData = {
    name: [],
    value: []
}
const initEventAreaEcharts = () => {
    if (!areaChars) {
        areaChars = echarts.init(eventAreaEcharts.value)
    }
    const color = colorTools().initColor(areaFilterData.name.length)
    const option = {
        title: {
            text: '事件区域分布',
            textStyle: {
                fontSize: 14,
                fontWeight: 'bold'
            }
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'shadow'
            }
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        xAxis: {
            type: 'category',
            data: areaFilterData.name,
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                data: areaFilterData.value,
                type: 'bar',
                label: {
                    show: true, // 显示柱子上的标签
                    position: 'inside', // 标签位置，'top' 表示在柱子上方
                    formatter: '{c}', // 格式化标签内容，这里直接显示数值
                    color: '#fff', // 标签文字颜色
                    fontSize: 14 // 标签文字大小
                },
                itemStyle: {
                    // 给每个柱子设置颜色
                    color: (params) => {
                        return new echarts.graphic.LinearGradient(
                            0,
                            0,
                            0,
                            1, // 渐变方向（从上到下）
                            [
                                {
                                    offset: 0,
                                    color: color[
                                        params.dataIndex % color.length
                                    ]
                                }, // 起始颜色
                                { offset: 1, color: '#ccc' } // 结束颜色（可以选择透明色或者其他颜色）
                            ]
                        )
                    }
                }
            }
        ]
    }

    areaChars.setOption(option)
}
const eventGuardEcharts = ref(null)

let guardChars = null
const initEventGuardEcharts = () => {
    if (!guardChars) {
        guardChars = echarts.init(eventGuardEcharts.value)
    }
    const tooltip = {
        trigger: 'axis',
        formatter: '{b}: {c}',
        axisPointer: {
            type: 'shadow'
        }
    }
    const color = colorTools().initColor(everyDayData.value.name.length)
    const option = {
        title: {
            text: '事件每日更新统计',
            textStyle: {
                fontSize: 14,
                fontWeight: 'bold'
            }
        },
        tooltip: tooltip,
        legend: {
            data: ['事件新增', '消警']
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: everyDayData.value.name
        },
        yAxis: {
            type: 'value',
            minInterval: 1 // 设置最小刻度间隔为1，确保刻度值为整数
        },
        series: [
            {
                name: '事件新增',
                type: 'line',
                stack: 'Total',
                data: everyDayData.value.value,
                label: {
                    show: true, // 显示柱子上的标签
                    position: 'inside', // 标签位置，'top' 表示在柱子上方
                    formatter: '{c}', // 格式化标签内容，这里直接显示数值
                    color: '#fff', // 标签文字颜色
                    fontSize: 14 // 标签文字大小
                },
                itemStyle: {
                    // 给每个柱子设置颜色
                    color: (params) => {
                        return new echarts.graphic.LinearGradient(
                            0,
                            0,
                            0,
                            1, // 渐变方向（从上到下）
                            [
                                {
                                    offset: 0,
                                    color: color[
                                        params.dataIndex % color.length
                                    ]
                                }, // 起始颜色
                                { offset: 1, color: '#ccc' } // 结束颜色（可以选择透明色或者其他颜色）
                            ]
                        )
                    }
                }
            },
            {
                name: '消警',
                type: 'line',
                stack: 'Total',
                data: everyDayData.value.handle,
                label: {
                    show: true, // 显示柱子上的标签
                    position: 'inside', // 标签位置，'top' 表示在柱子上方
                    formatter: '{c}', // 格式化标签内容，这里直接显示数值
                    color: '#fff', // 标签文字颜色
                    fontSize: 14 // 标签文字大小
                },
                itemStyle: {
                    // 给每个柱子设置颜色
                    color: (params) => {
                        return new echarts.graphic.LinearGradient(
                            0,
                            0,
                            0,
                            1, // 渐变方向（从上到下）
                            [
                                {
                                    offset: 0,
                                    color: color[
                                        params.dataIndex % color.length
                                    ]
                                }, // 起始颜色
                                { offset: 1, color: '#ccc' } // 结束颜色（可以选择透明色或者其他颜色）
                            ]
                        )
                    }
                }
            }
        ]
    }

    guardChars.setOption(option)
}
const searchForm = ref({})
const total = ref({})
const level = ref({})
const type = ref({})
const area = ref({})
const currentArea = ref()
let areaDataConfig = {}

const treeProps = {
    label: 'name',
    value: 'id',
    children: 'children'
}

const areaTree = ref([
    {
        id: 0,
        name: '全部区域',
        children: []
    }
])
const getDeviceTree = async () => {
    const result = await DeviceApi().getGroupTree()
    const selectedDefArea = []
    areaDataConfig = {}

    if (result.code == 1) {
        areaTree.value = result.data.map(item => {
            areaDataConfig[item.id] = item.name
            selectedDefArea.push(item.id)

            if (Array.isArray(item.children)) {
                item.children.map(child => {
                    areaDataConfig[child.id] = child.name
                    selectedDefArea.push(child.id)
                    return child
                })
            }

            return item
        })

        currentArea.value = selectedDefArea

        getEventStatistics()
        // getWorkLogs()
        getEventEveryDay()
        initEventHandleTime()
    }
}

const workLogs = ref([])
const getWorkLogs = () => {
    http.get('/v1/event/workLogs').then(res => {
        if (res.code == 1) {
            workLogs.value = res.data
        }
    })
}
const everyDayData = ref({})
const getEventEveryDay = () => {
    const postData = {
        time: formatDate(rangeDate.value, 'YYYY-MM-DD')
    }
    http.get('/v1/event/eventEveryDay', { params: postData }).then(res => {
        if (res.code == 1) {
            everyDayData.value = res.data
            initEventGuardEcharts()
        }
    })
}

const quarterMap = {
    1: { start: 1, end: 3 },
    2: { start: 4, end: 6 },
    3: { start: 7, end: 9 },
    4: { start: 10, end: 12 }
}

const getEventStatistics = () => {
    const postData = {
        type: rangeType.value
    }

    switch (rangeType.value) {
        // 按年
        case 1:
            postData.time = formatDate(rangeDate.value, 'YYYY')
            break
        // 按季
        case 2:
            const quarter = quarterMap[rangeDate.value]
            const date = getDate(new Date())
            postData.time = [
                formatDate(new Date(date.year, quarter.start - 1, 1), 'YYYY-MM-DD 00:00:00'),
                formatDate(new Date(date.year, quarter.end, 0), 'YYYY-MM-DD 23:59:59')
            ]
            break
        // 按月
        case 3:
            postData.time = formatDate(rangeDate.value, 'YYYY-MM')
            break
        // 按周
        case 4:
            console.log('🚀 ~ getEventStatistics ~ rangeDate.value:', rangeDate.value)
            const { startDate, endDate } = getWeekRangeOfYear(rangeDate.value)
            postData.time = [
                formatDate(startDate, 'YYYY-MM-DD 00:00:00'),
                formatDate(endDate, 'YYYY-MM-DD 23:59:59')
            ]
            break
        // 具体年月日
        case 5:
            postData.time = formatDate(rangeDate.value, 'YYYY-MM-DD')
            break
        // 自定义区间
        case 6:
            if (Array.isArray(rangeDate.value)) {
                postData.time = [
                    formatDate(rangeDate.value[0], 'YYYY-MM-DD hh:mm:ss'),
                    formatDate(rangeDate.value[1], 'YYYY-MM-DD hh:mm:ss')
                ]
            } else {
                postData.time = undefined
            }
            break
        default:
            break
    }

    http.get('/v1/event/statistics', { params: postData }).then(res => {
        if (res.code == 1) {
            var data = res.data
            total.value = {
                total: data.total,
                handle: data.handle,
                serious: data.serious,
                handle_lv: data.handle_lv,
                serious_lv: data.serious_lv
            }
            level.value = data.level
            type.value = data.type
            area.value = data.area

            handleChangeArea()
            initEventTypeEcharts()
            initEventLevelEcharts()
        }
    })
}

const rangeType = ref(5)
const rangeDate = ref(new Date())
const typeMap = {
    1: {
        type: 'year',
        placeholder: '选择年份',
        defaultTime: new Date(),
        format: 'YYYY',
        value: '2024'
    },
    2: {
        type: 'monthrange',
        placeholder: '选择季度',
        defaultTime: [
            new Date(),
            new Date()
        ]
    },
    3: {
        type: 'month',
        placeholder: '选择月份',
        defaultTime: new Date(),
        format: 'YYYY-MM'
    },
    4: {
        type: 'week',
        placeholder: '选择周',
        defaultTime: new Date(),
        format: "第 ww 周"
    },
    5: {
        type: 'date',
        placeholder: '选择日',
        defaultTime: new Date(),
        format: "YYYY-MM-DD"
    },
    6: {
        type: 'datetimerange',
        placeholder: '选择日期',
        defaultTime: [
            new Date(2000, 1, 1, 0, 0, 0),
            new Date(2000, 2, 1, 23, 59, 59)
        ],
        format: 'YYYY-MM-DD HH:mm:ss'
    }
}

const dateConfig = computed(() => {
    return typeMap[rangeType.value]
})

const handleChangeDateType = (type) => {
    if (rangeType.value === type) {
        return
    }

    rangeType.value = type

    switch (rangeType.value) {
        // 按年
        case 1:
            rangeDate.value = new Date()
            break
        // 按季
        case 2:
            rangeDate.value = 1
            break
        // 按月
        case 3:
            rangeDate.value = new Date()
            break
        // 按周
        case 4:
            rangeDate.value = new Date()
            break
        // 具体年月日
        case 5:
            rangeDate.value = new Date()
            break
        // 自定义区间
        case 6:
            rangeDate.value = [
                formatDate(new Date(), 'YYYY-MM-DD 00:00:00'),
                formatDate(new Date(), 'YYYY-MM-DD 23:59:59')
            ]
            break
        default:
            break
    }

    handleChangeDate()
}

const handleChangeDate = () => {
    if (rangeType.value == 5) {
        getEventEveryDay()
        initEventHandleTime()
    }

    getEventStatistics()
}

const handleChangeArea = () => {
    // console.log(areaDataConfig)
    areaFilterData = {
        name: [],
        value: []
    }

    currentArea.value.map(item => {
        const index = area.value.name.findIndex(name => name == areaDataConfig[item])
        // console.log('🚀 ~ handleChangeArea ~ index:', index)

        if (index < 0) {
            return
        }

        areaFilterData.name.push(area.value.name[index])
        areaFilterData.value.push(area.value.value[index])
    })

    initEventAreaEcharts()
}

getDeviceTree()

const downData = async () => {
    const types = {}
    type.value.value.map((item) => {
        types[item.name] = item.value
    })
    const levels = {}
    level.value.value.map((item) => {
        levels[item.name] = item.value
    })
    const areas = {}
    area.value.name.map((item, index) => {
        areas[item] = area.value.value[index]
    })
    const alarms = []
    everyDayData.value.name.map((item, index) => {
        alarms.push({
            name: item,
            value: everyDayData.value.value[index],
            handle: everyDayData.value.handle[index]
        })

    })
    const params = {
        types: types,
        levels: levels,
        areas: areas,
        alarms: alarms
    }
    const loading = ElLoading.service({
        lock: true,
        text: '正在导出...',
        background: 'rgba(0, 0, 0, 0.7)',
    })
    try {
        // 向后端请求导出文件
        const response = await fetchDownData(params)
        // 隐藏“正在导出”提示框
        loading.close()
        // 创建下载链接并触发下载
        const blob = response
        const link = document.createElement('a')
        const fileName = '事件统计表' + new Date().toLocaleString() + '.xlsx'  // 你可以动态设置文件名，或从后端获取
        link.href = URL.createObjectURL(blob)
        link.download = fileName  // 设置文件下载的名字
        link.click()  // 触发下载
    } catch (error) {
        // 处理错误
        loading.close()
        ElMessage.error('导出失败')
    }
}

const handleTimes = ref({})
const initEventHandleTime = async () => {
    const params = {
        date: formatDate(rangeDate.value, 'YYYY-MM-DD')
    }
    const result = await fetchEventHandle(params)
    if (result.code == 1) {
        handleTimes.value = result.data
        initEventHandleTimesEcharts()
    }
}

/**
 * 事件处理时间图表
 * */
let handleTimesCharts = null
const initEventHandleTimesEcharts = () => {
    if (!handleTimesCharts) {
        handleTimesCharts = echarts.init(eventHandleRef.value)
    }
    const data = handleTimes.value.value || []
    let color = colorTools().initColor(data.length)
    data.forEach((item, index) => {
        item.itemStyle = { color: color[index] }
    })
    const option = {
        title: {
            text: '事件处理时长统计',
            textStyle: {
                fontSize: 14,
                fontWeight: 'bold'
            }
        },
        tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c}' + 's'
        },
        legend: {
            bottom: 10,
            left: 'center',
            data: handleTimes.value.name
        },
        series: [
            {
                name: '事件处理时长',
                type: 'pie',
                radius: ['0%', '55%'],
                center: ['50%', '45%'],
                selectedMode: 'single',
                data: data,
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                },
                label: {
                    show: true, // 显示标签
                    position: 'outside', // 标签位置在外侧
                    formatter: '{b}: {c}' + 's', // 标签显示格式
                    fontSize: 12
                },
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                }
            }
        ]
    }

    handleTimesCharts.setOption(option)
}
</script>
<template>
    <div :class="$style['main-container']">
        <el-form :inline="true" label-position="left" :class="$style['form-wrapper']" label-width="auto"
            :model="searchForm">
            <el-form-item label="时间范围">
                <el-button-group :class="$style['date-group']">
                    <el-button :on="rangeType == 1 ? '' : null" @click="handleChangeDateType(1)">年</el-button>
                    <el-button :on="rangeType == 2 ? '' : null" @click="handleChangeDateType(2)">季</el-button>
                    <el-button :on="rangeType == 3 ? '' : null" @click="handleChangeDateType(3)">月</el-button>
                    <el-button :on="rangeType == 4 ? '' : null" @click="handleChangeDateType(4)">周</el-button>
                    <el-button :on="rangeType == 5 ? '' : null" @click="handleChangeDateType(5)">日</el-button>
                    <el-button :on="rangeType == 6 ? '' : null" @click="handleChangeDateType(6)">自定义</el-button>
                </el-button-group>

                <el-date-picker v-model="rangeDate" :class="$style['date-picker']" :type="dateConfig.type"
                    :clearable="false" :default-time="dateConfig.defaultTime" :format="dateConfig.format"
                    :value-format="dateConfig.valueFormat" :placeholder="dateConfig.placeholder" range-separator="~"
                    start-placeholder="开始日期" end-placeholder="结束日期" @change="handleChangeDate" v-if="rangeType != 2" />
                <el-select v-model="rangeDate" :class="$style['date-quarter']" @change="handleChangeDate" v-else>
                    <el-option :value="1" label="第一季度"></el-option>
                    <el-option :value="2" label="第二季度"></el-option>
                    <el-option :value="3" label="第三季度"></el-option>
                    <el-option :value="4" label="第四季度"></el-option>
                </el-select>
            </el-form-item>
            <el-link type="primary" :underline="false" :icon="Download" @click="downData">
                数据导出
            </el-link>
        </el-form>
        <div :class="$style['overview-container']">
            <h1>事件概览</h1>
            <div :class="$style['overview-wrapper']">
                <div :class="$style['overview-item']">
                    <p>事件总数</p>
                    <p>{{ total.total }}</p>
                </div>
                <div :class="$style['overview-item']">
                    <p>已消警</p>
                    <p>{{ total.handle }}</p>
                </div>
                <div :class="$style['overview-item']">
                    <p>消警率</p>
                    <p>{{ total.handle_lv }}</p>
                </div>
                <div :class="$style['overview-item']">
                    <p>严重告警数量</p>
                    <p>{{ total.serious }}</p>
                </div>
                <div :class="$style['overview-item']">
                    <p>严重告警占比</p>
                    <p>{{ total.serious_lv }}</p>
                </div>
            </div>
        </div>
        <div :class="$style['echarts-container']">
            <div :class="$style['echrts-item-relative']">
                <div ref="eventTypeEcharts"> </div>
                <el-tree-select v-model="currentArea" multiple size="small" placeholder="请选择区域" :data="areaTree"
                    node-key="id" check-strictly :props="treeProps" :default-checked-keys="currentArea" show-checkbox
                    default-expand-all collapse-tags :expand-on-click-node="false" @change="handleChangeArea" />
                <div ref="eventAreaEcharts"></div>
            </div>
            <div :class="$style['echrts-item-center']">
                <div ref="eventLevelEcharts"></div>
                <div ref="eventGuardEcharts"></div>
            </div>

            <!--安保人员工作明细 这个是飞行区围界的需求 暂时注释掉-->
            <!-- <div :class="$style['echrts-item']">
                <div style="margin-bottom: 10px">安保人员工作明细</div>
                <el-table :data="workLogs" size="small" :class="$style['table-wrapper']">
                    <el-table-column prop="name" label="坐席" align="center" />
                    <el-table-column prop="handle_lv" label="消警完成率" align="center" />
                    <el-table-column prop="new_event" label="新增事件" align="center" />
                    <el-table-column prop="handle" label="消警数量" align="center" />
                </el-table>
            </div> -->
            <div ref="eventHandleRef" :class="$style['echrts-item']"> </div>
        </div>
    </div>
</template>
<style lang="scss" module>
.main-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 0 10px 10px 10px;
    background: #FFF;
    border-radius: 5px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.form-wrapper {
    display: flex;
    height: 50px;
    align-items: center;

    & [class~="el-form-item"] {
        margin-bottom: 0;
        margin-right: 10px;
    }
}

.overview-container {
    height: 130px;
    display: flex;
    flex-direction: column;
    padding: 10px;
    border: 1px solid #ccc;
    margin-bottom: 10px;

    >h1 {
        font-weight: bold;
    }
}

.overview-wrapper {
    flex: 1;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}

.overview-item {
    display: flex;
    flex-direction: column;
    width: 20%;
    justify-content: center;
    align-items: center;

    & :nth-child(1) {
        font-weight: 500;
        font-size: 15px;
    }

    & :nth-child(2) {
        font-size: 14px;
    }
}

.echarts-container {
    flex: 1;
    overflow: hidden;
    display: flex;
    flex-direction: row;
    justify-content: space-between;

    & :nth-not-child(3) {
        display: flex;
        flex-direction: column;
    }
}

.echrts-item-relative {
    position: relative;
    flex: 1.2;
    margin-right: 15px;
    display: flex;
    flex-direction: column;
    gap: 15px;

    > :nth-child(1) {
        flex: 1;
        border: 1px solid #ccc;
        padding: 5px;
    }

    > :nth-child(2) {
        position: absolute;
        top: calc(50% + 15px);
        right: 10px;
        z-index: 1;
        max-width: 200px;
    }

    > :nth-child(3) {
        flex: 1;
        border: 1px solid #ccc;
        padding: 5px;
    }
}

.echrts-item-center {
    flex: 1.2;
    margin-right: 15px;
    display: flex;
    flex-direction: column;
    gap: 15px;
    box-sizing: border-box;

    & :nth-child(1) {
        flex: 1;
        border: 1px solid #ccc;
    }

    & :nth-child(2) {
        flex: 1;
        border: 1px solid #ccc;
    }
}

.echrts-item {
    flex: 1;
    border: 1px solid #ccc;
    padding: 10px;
    box-sizing: border-box;
}

.table-wrapper {
    flex: 1;
}


.date-group {
    &>button:last-child {
        border-radius: 0;
    }

    & button {
        &[on] {
            background-color: var(--el-button-hover-bg-color);
            border-color: var(--el-button-hover-border-color);
            color: var(--el-button-hover-text-color);
            outline: none;
        }
    }
}

.date-picker {
    margin-left: -1px;
    border-bottom-left-radius: 0;
    border-top-left-radius: 0;

    & [class~="el-input__wrapper"] {
        border-bottom-left-radius: 0;
        border-top-left-radius: 0;
    }
}

.date-quarter {
    width: 220px;
    margin-left: -1px;

    &>[class~="el-select__wrapper"] {
        border-bottom-left-radius: 0;
        border-top-left-radius: 0;
    }
}
</style>
